package com.ecoolex.ying.space.api.graphql;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;

import com.alibaba.fastjson.JSONArray;
import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.util.Assert;
import com.ecoolex.framework.common.util.BeanUtil;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMember;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberAuthority;
import com.ecoolex.framework.modularize.api.auth.user.ConsumerMemberManager;
import com.ecoolex.framework.modularize.api.service.storage.StorageInfo;
import com.ecoolex.framework.modularize.api.service.storage.StorageService;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module;
import com.ecoolex.framework.web.api.graphql2.annotation.GraphQL2Module.Type;
import com.ecoolex.framework.web.api.graphql2.annotation.MutationField;
import com.ecoolex.framework.web.api.graphql2.annotation.QueryField;
import com.ecoolex.framework.web.api.graphql2.annotation.Source;
import com.ecoolex.framework.web.api.graphql2.annotation.TypeField;
import com.ecoolex.ying.space.entity.OutsourcingGoodsWithBLOBs;
import com.ecoolex.ying.space.entity.OutsourcingPackaged;
import com.ecoolex.ying.space.entity.UserWorks;
import com.ecoolex.ying.space.entity.UserWorksImages;
import com.ecoolex.ying.space.entity.UserWorksOpus;
import com.ecoolex.ying.space.entity.UserWorksOpusItems;
import com.ecoolex.ying.space.entity.UserWorksShopping;
import com.ecoolex.ying.space.entity.UserWorksStatistical;
import com.ecoolex.ying.space.entity.UserWorksVideo;
import com.ecoolex.ying.space.enums.UserLikeRecordType;
import com.ecoolex.ying.space.pojo.AddUserWorksImageDTO;
import com.ecoolex.ying.space.pojo.AddUserWorksVideoDTO;
import com.ecoolex.ying.space.pojo.QueryShopWindowGoodsDTO;
import com.ecoolex.ying.space.pojo.QueryUserWorksShoppingLinkDTO;
import com.ecoolex.ying.space.pojo.UserWorksImageDTO;
import com.ecoolex.ying.space.pojo.UserWorksOpusItemImageDTO;
import com.ecoolex.ying.space.ws.OutsourcingGoodsService;
import com.ecoolex.ying.space.ws.UserFavoriteItemsService;
import com.ecoolex.ying.space.ws.UserLikeRecordService;
import com.ecoolex.ying.space.ws.UserWatchService;
import com.ecoolex.ying.space.ws.UserWorksService;


@GraphQL2Module(type = Type.User, description = "用户作品、灵感管理")
public class UserWorksGraphql {

    @Autowired
    private StorageService storageService;

    @Reference
    private UserWorksService userWorksService;

    @Autowired
    private ConsumerMemberManager consumerMemberManager;

    @Reference
    private OutsourcingGoodsService outsourcingGoodsService;

    @Reference
    private UserWatchService userWatchService;

    @Reference
    private UserFavoriteItemsService userFavoriteItemsService;

    @Reference
    private UserLikeRecordService userLikeRecordService;

    @TypeField(type = UserWorks.class, field = "ifMyWorks", description = "是否是自己的作品")
    public boolean ifMyWorks(@Source UserWorks source, ConsumerMemberAuthority user) {
        if (user.isLogin()) {
            return user.userId().equals(source.getUserId()) ? true
                : false;
        }
        return false;
    }

    @TypeField(type = UserWorks.class, field = "userWorksStatistical", description = "作品统计数据")
    public UserWorksStatistical getUserWorksStatistical(@Source UserWorks source) {
        return userWorksService.getUserWorksStatisticalByWorksId(source.getWorksId());
    }

    @TypeField(type = UserWorks.class, field = "releaseUser", description = "发布用户")
    public ConsumerMember getCommentUser(@Source UserWorks source) {
        return consumerMemberManager.getByUserId(source.getUserId());
    }

    @TypeField(type = UserWorks.class, field = "ifCollection", description = "是否收藏了")
    public boolean ifCollection(@Source UserWorks source, ConsumerMemberAuthority user) {
        if (user.isLogin()) {
            return userFavoriteItemsService.getUserFavoriteItemsByUserIdAndContentId(user.userId(),
                source.getWorksId()) == null ? false
                    : true;
        }
        return false;
    }

    @TypeField(type = UserWorks.class, field = "ifPrase", description = "是否点赞了")
    public boolean ifPrase(@Source UserWorks source, ConsumerMemberAuthority user) {
        if (user.isLogin()) {
            return userLikeRecordService.getByUserIdAndTypeAndContentId(user.userId(),
                UserLikeRecordType.USERWORKS.real(),
                source.getWorksId()) == null ? false
                    : true;
        }
        return false;
    }

    @TypeField(type = UserWorks.class, field = "coverImage", description = "作品封面图")
    public StorageInfo coverImage(@Source UserWorks source) {
        return storageService.get(source.getCoverImage());
    }

    @TypeField(type = UserWorksImages.class, field = "images", description = "图文灵感辑的图片")
    public List<StorageInfo> image(@Source UserWorksImages source) {
        JSONArray array = JSONArray.parseArray(source.getImages());
        List<String> storageIdList = array.toJavaList(String.class);
        return storageIdList.stream().map(storageId -> storageService.get(storageId)).collect(Collectors.toList());
    }

    @TypeField(type = UserWorksImages.class, field = "imageList", description = "图文灵感辑的图片")
    public List<UserWorksImageDTO> images(@Source UserWorksImages source) {
        JSONArray array = JSONArray.parseArray(source.getImages());
        List<String> storageIdList = array.toJavaList(String.class);
        return storageIdList.stream().map(storageId -> new UserWorksImageDTO(storageId)).collect(Collectors.toList());
    }

    @TypeField(type = UserWorksImageDTO.class, field = "image", description = "灵感图片")
    public StorageInfo images(@Source UserWorksImageDTO source) {
        return storageService.get(source.getImage());
    }

    @TypeField(type = UserWorksImageDTO.class, field = "shoppings", description = "图片购物信息")
    public List<UserWorksShopping> imageShopping(@Source UserWorksImageDTO source) {
        return userWorksService.getUserWorksShoppingByStorageId(source.getImage());
    }

    @TypeField(type = UserWorksOpusItems.class, field = "opusImages", description = "作品栏目的图片")
    public List<StorageInfo> opusImages(@Source UserWorksOpusItems source) {
        JSONArray array = JSONArray.parseArray(source.getImages());
        List<String> storageIdList = array.toJavaList(String.class);
        return storageIdList.stream().map(storageId -> storageService.get(storageId)).collect(Collectors.toList());
    }

    @TypeField(type = UserWorksOpusItems.class, field = "opusImageList", description = "作品栏目的图片集合")
    public List<UserWorksOpusItemImageDTO> opusImageList(@Source UserWorksOpusItems source) {
        JSONArray array = JSONArray.parseArray(source.getImages());
        List<String> storageIdList = array.toJavaList(String.class);
        return storageIdList.stream().map(storageId -> new UserWorksOpusItemImageDTO(storageId)).collect(
            Collectors.toList());
    }

    @TypeField(type = UserWorksOpusItemImageDTO.class, field = "image", description = "灵感图片")
    public StorageInfo images(@Source UserWorksOpusItemImageDTO source) {
        return storageService.get(source.getImage());
    }

    @TypeField(type = UserWorksOpusItemImageDTO.class, field = "shoppings", description = "图片购物信息")
    public List<UserWorksShopping> imageShopping(@Source UserWorksOpusItemImageDTO source) {
        return userWorksService.getUserWorksShoppingByStorageId(source.getImage());
    }

    @TypeField(type = UserWorksVideo.class, field = "video", description = "视频灵感辑的视频")
    public StorageInfo video(@Source UserWorksVideo source) {
        return storageService.get(source.getVideo());
    }

    @TypeField(type = UserWorks.class, field = "userWorksImages", description = "图文灵感辑")
    public UserWorksImages userWorksImages(@Source UserWorks userWorks) {
        return userWorksService.getUserWorksImagesByWorksId(userWorks.getWorksId());
    }

    @TypeField(type = UserWorks.class, field = "userWorksVideo", description = "视频灵感辑")
    public UserWorksVideo userWorksVideo(@Source UserWorks userWorks) {
        return userWorksService.getUserWorksVideoByWorksId(userWorks.getWorksId());
    }

    @TypeField(type = UserWorks.class, field = "userWorksOpus", description = "作品")
    public UserWorksOpus userWorksOpus(@Source UserWorks userWorks) {
        return userWorksService.getUserWorksOpusByWorksId(userWorks.getWorksId());
    }

    @TypeField(type = UserWorksOpus.class, field = "userWorksOpusItems", description = "作品栏目")
    public List<UserWorksOpusItems> userWorksOpusItems(@Source UserWorksOpus source) {
        return userWorksService.getUserWorksOpusItemsByWorksId(source.getWorksId());
    }

    @TypeField(type = UserWorksShopping.class, field = "outsourcingGoods", description = "外购商品")
    public OutsourcingGoodsWithBLOBs getOutsourcingGoods(@Source UserWorksShopping source) {
        return outsourcingGoodsService.getOutsourcingGoodsById(source.getGoodsId());
    }

    @TypeField(type = UserWorksShopping.class, field = "outsourcingPackaged", description = "外购套餐")
    public OutsourcingPackaged getOutsourcingPackaged(@Source UserWorksShopping source) {
        return outsourcingGoodsService.getOutsourcingPackagedById(source.getPackagedId());
    }

    @TypeField(type = UserWorks.class, field = "userWorksShopping", description = "作品购物信息")
    public Pagination<QueryShopWindowGoodsDTO> userWorksShopping(@Source UserWorks source, @NonNull Sorting[] sorts, @NonNull Page page) {
        return userWorksService.queryShopWindowGoodsByWorksId(source.getWorksId(), sorts, page);
    }

    @TypeField(type = QueryShopWindowGoodsDTO.class, field = "shopWindowGoods", description = "橱窗商品")
    public OutsourcingGoodsWithBLOBs shopWindowGoods(@Source QueryShopWindowGoodsDTO source) {
        return outsourcingGoodsService.getOutsourcingGoodsByIdForH5(source.getGoodsId());
    }

    @TypeField(type = QueryShopWindowGoodsDTO.class, field = "shopWindowPackaged", description = "橱窗套餐")
    public OutsourcingPackaged shopWindowPackaged(@Source QueryShopWindowGoodsDTO source) {
        return outsourcingGoodsService.getOutsourcingPackagedByIdForH5(source.getPackagedId());
    }

    @TypeField(type = QueryShopWindowGoodsDTO.class, field = "shopWindowLink", description = "橱窗外链商品")
    public QueryUserWorksShoppingLinkDTO shopWindowLink(@Source QueryShopWindowGoodsDTO source) {
        UserWorksShopping userWorksShopping = userWorksService.getUserWorksShoppingById(source.getLinkId());
        if (Check.notNull(userWorksShopping)) {
            return BeanUtil.copy(userWorksShopping, new QueryUserWorksShoppingLinkDTO());
        }
        return null;
    }

    @QueryField(field = "userWorks", description = "作品、灵感辑详情")
    public UserWorks get(@NonNull Integer worksId) {
        return userWorksService.getUserWorksByIdForH5(worksId);
    }

    @QueryField(field = "userWorksList", description = "首页作品、灵感辑推荐列表")
    public Pagination<UserWorks> query(String title, Integer worksType, @NonNull Date now, @NonNull Sorting[] sorts, @NonNull Page page) {
        return userWorksService.queryForH5(title, worksType, now, sorts, page);
    }

    @QueryField(field = "watchUserWorksList", description = "首页作品、灵感辑关注列表")
    public Pagination<UserWorks> queryWatch(String title, Integer worksType, @NonNull Date now, @NonNull Sorting[] sorts, @NonNull Page page, ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.queryWatchForH5(user.userId(), title, worksType, now, sorts, page);
    }

    @QueryField(field = "myUserWorks", description = "我的作品、灵感辑详情")
    public UserWorks myUserWorks(@NonNull Integer worksId, ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.getByIdAndUserId(worksId, user.userId());
    }

    @QueryField(field = "myUserWorksOpusList", description = "我的发布作品列表")
    public Pagination<UserWorks> queryMyReleaseOpus(String title, Integer worksType, @NonNull Sorting[] sorts, @NonNull Page page, ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.queryMyUserWorksOpusForH5(title, worksType, user.userId(), sorts, page);
    }

    @QueryField(field = "myUserWorksList", description = "我的发布灵感列表")
    public Pagination<UserWorks> queryMyRelease(String title, @NonNull Sorting[] sorts, @NonNull Page page, ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.queryMyUserWorksForH5(title, user.userId(), sorts, page);
    }

    @QueryField(field = "myUserWorksOpusCount", description = "我的发布作品数量")
    public long queryMyUserWorksOpusCount(Integer worksType, ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.queryMyUserWorksCountOpusForH5(worksType, user.userId());
    }

    @QueryField(field = "myUserWorksCount", description = "我的发布灵感数量")
    public long queryMyUserWorksCount(ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.queryMyUserWorksCountForH5(user.userId());
    }

    @QueryField(field = "otherUserWorksOpusList", description = "他人发布作品列表")
    public Pagination<UserWorks> queryOtherReleaseOpus(String title, @NonNull Integer otherUserId, @NonNull Sorting[] sorts, @NonNull Page page) {
        return userWorksService.queryOtherUserWorksOpusForH5(title, otherUserId, sorts, page);
    }

    @QueryField(field = "otherUserWorksList", description = "他人发布灵感列表")
    public Pagination<UserWorks> queryOtherRelease(String title, @NonNull Integer otherUserId, @NonNull Sorting[] sorts, @NonNull Page page) {
        return userWorksService.queryOtherUserWorksForH5(title, otherUserId, sorts, page);
    }

    @QueryField(field = "otherUserWorksOpusCount", description = "他人发布作品数量")
    public long queryOtherUserWorksOpusCount(@NonNull Integer otherUserId, ConsumerMemberAuthority user) {
        return userWorksService.queryOtherUserWorksOpusCountForH5(otherUserId);
    }

    @QueryField(field = "otherUserWorksCount", description = "他人发布灵感数量")
    public long queryOtherUserWorksCount(@NonNull Integer otherUserId, ConsumerMemberAuthority user) {
        return userWorksService.queryOtherUserWorksCountForH5(otherUserId);
    }

    @QueryField(field = "myShopWindowUserWorksList", description = "我的橱窗内容列表")
    public Pagination<UserWorks> queryMyShopWindowUserWorks(String title, Integer worksType, @NonNull Sorting[] sorts, @NonNull Page page, ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.queryMyShopWindowUserWorks(title, worksType, user.userId(), sorts, page);
    }

    @QueryField(field = "myShopWindowGoodsList", description = "我的橱窗商品列表")
    public Pagination<QueryShopWindowGoodsDTO> queryMyShopWindowGoods(@NonNull Sorting[] sorts, @NonNull Page page, ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.queryShopWindowGoodsByUserId(user.userId(), sorts, page);
    }

    @QueryField(field = "myShopWindowGoodsCount", description = "我的橱窗商品数量")
    public long queryMyShopWindowGoodsCount(ConsumerMemberAuthority user) {
        user.assertLogin();
        return userWorksService.queryShopWindowGoodsCountByUserId(user.userId());
    }

    @QueryField(field = "otherShopWindowGoodsList", description = "他人商品列表")
    public Pagination<QueryShopWindowGoodsDTO> queryOtherShopWindowGoods(@NonNull Integer userId, @NonNull Sorting[] sorts, @NonNull Page page) {
        return userWorksService.queryShopWindowGoodsByUserId(userId, sorts, page);
    }

    @QueryField(field = "otherShopWindowGoodsCount", description = "他人商品数量")
    public long queryOtherShopWindowGoodsCount(@NonNull Integer userId) {
        return userWorksService.queryShopWindowGoodsCountByUserId(userId);
    }

    @QueryField(field = "searchByKeyword", description = "首页搜索")
    public Pagination<UserWorks> searchByKeyword(@NonNull String keyword, Page page) {
        return userWorksService.queryBySearchKeyword(keyword, page);
    }

    

    @MutationField(field = "addUserWorksImages", description = "添加图文灵感辑")
    public UserWorks addUserWorksImages(@NonNull AddUserWorksImageDTO addUserWorksImageDTO, ConsumerMemberAuthority user) {
        user.assertLogin();

        return userWorksService.addUserWorksImages(addUserWorksImageDTO, user.userId(), user.userName());
    }

    @MutationField(field = "addUserWorksVideo", description = "添加视频灵感辑")
    public UserWorks addUserWorksVideo(@NonNull AddUserWorksVideoDTO addUserWorksVideoDTO, ConsumerMemberAuthority user) {
        user.assertLogin();

        return userWorksService.addUserWorksVideo(addUserWorksVideoDTO, user.userId(), user.userName());
    }

    // @MutationField(field = "editUserWorksImages", description = "编辑图文灵感辑")
    // public UserWorks editUserWorksImages(@NonNull EditUserWorksDTO editUserWorksDTO, @NonNull EditUserWorksImageDTO
    // editUserWorksImageDTO, ConsumerMemberAuthority user) {
    // user.assertLogin();
    // UserWorks old = userWorksService.getUserWorksById(editUserWorksDTO.getWorksId());
    // Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "图文灵感辑不存在");
    //
    // BeanUtil.copy(editUserWorksDTO,
    // old,
    // Lists.newArrayList(Column.deleted, Column.createUser, Column.createTime).stream().map(
    // Column::getJavaProperty).toArray(String[]::new));
    // return userWorksService.editUserWorksImages(old, editUserWorksImageDTO, user.userId(), user.userName());
    // }
    //
    // @MutationField(field = "editUserWorksVideo", description = "编辑视频灵感辑")
    // public UserWorks editUserWorksVideo(@NonNull EditUserWorksDTO editUserWorksDTO, @NonNull EditUserWorksVideoDTO
    // editUserWorksVideoDTO, ConsumerMemberAuthority user) {
    // user.assertLogin();
    // UserWorks old = userWorksService.getUserWorksById(editUserWorksDTO.getWorksId());
    // Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "图文灵感辑不存在");
    //
    // BeanUtil.copy(editUserWorksDTO,
    // old,
    // Lists.newArrayList(Column.deleted, Column.createUser, Column.createTime).stream().map(
    // Column::getJavaProperty).toArray(String[]::new));
    // return userWorksService.editUserWorksVideo(old, editUserWorksVideoDTO, user.userId(), user.userName());
    // }

    @MutationField(field = "delUserWorksImages", description = "删除图文灵感辑")
    public boolean deleteUserWorksImages(@NonNull Integer worksId, ConsumerMemberAuthority user) {
        user.assertLogin();
        UserWorks old = userWorksService.getUserWorksById(worksId);
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "图文灵感辑不存在");
        userWorksService.deleteUserWorksImages(old, user.userName());
        return true;
    }

    @MutationField(field = "delUserWorksVideo", description = "删除视频灵感辑")
    public boolean deleteUserWorksVideo(@NonNull Integer worksId, ConsumerMemberAuthority user) {
        user.assertLogin();
        UserWorks old = userWorksService.getUserWorksById(worksId);
        Assert.isTrue(Check.notNull(old), ResultCode.VERIFY.build(1), "视频灵感辑不存在");
        userWorksService.deleteUserWorksVideo(old, user.userName());
        return true;
    }

}
